﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.CApC3DManagerApp
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using EngineeringInternalExtension.Options;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Forms;
using Tecnomatix.Engineering;


namespace DnProcessSimulateCommands;

internal class CApC3DManagerApp
{
  private CApC3DDataManagerApp m_dataManager = new CApC3DDataManagerApp();
  private CApC3DSimulationApp m_simulationApp = new CApC3DSimulationApp();
  private CApC3DSnapshotApp m_snapshotApp = new CApC3DSnapshotApp();
  private CApC3DDocumentationSettings m_documentationSettings;

  public event CApC3DManagerApp.CApC3DGeneratorApp_IncreaseProgressBarEventHandler IncreaseProgressBar;

  public void Initialize()
  {
    this.m_dataManager.Initialize();
    this.m_documentationSettings = this.m_dataManager.GetDocumentationSettings();
  }

  public CApC3DDocumentationSettings DocumentationSettings
  {
    get => this.m_documentationSettings;
    set => this.m_documentationSettings = value;
  }

  public bool ThreeDPDFLicense
  {
    get
    {
      bool threeDpdfLicense = true;
      if (this.DocumentationSettings.PdfMode == 1 && TxOptionsEx.PRCGenerator == 1)
        threeDpdfLicense = TxTcUtilities.ThreeDPDFLicense == 1;
      return threeDpdfLicense;
    }
  }

  public bool DoRootsHave3DData() => this.m_dataManager.DoRootsHave3DData();

  public bool DoRootsExistOnServer() => this.m_dataManager.DoRootsExistOnServer();

  public List<CApC3DProcessNodeData> GetProcesses() => this.m_dataManager.GetProcesses();

  public List<CApC3DProcessNodeData> GetOrderedProcesses()
  {
    return this.m_dataManager.GetOrderedProcesses();
  }

  public void FillAllSteps() => this.m_dataManager.FillAllSteps();

  public TxObjectList GetAllSnapshots() => this.m_snapshotApp.GetAllSnapshots();

  public void ProcessesToSteps(ArrayList processes)
  {
    foreach (CApC3DProcessNodeData process in processes)
      process.IsStep = true;
  }

  public void RemoveSteps(ArrayList processes)
  {
    foreach (CApC3DProcessNodeData process in processes)
      process.IsStep = false;
  }

  public bool StartGeneration(int stepNumber, Form parentForm)
  {
    bool flag = true;
    CUiC3DProgressBarForm dprogressBarForm = new CUiC3DProgressBarForm();
    dprogressBarForm.Initialize(this, (stepNumber + 2) * this.m_dataManager.Roots.Count);
    try
    {
      dprogressBarForm.ProcessCanceled += new CUiC3DProgressBarForm.CUiC3DProgressBarForm_ProcessCanceledEventHandler(this.progressForm_ProcessCanceled);
      dprogressBarForm.StartProcess += new CUiC3DProgressBarForm.CUiC3DProgressBarForm_StartProcessEventHandler(this.progressForm_StartProcess);
      return ((Form) dprogressBarForm).ShowDialog((IWin32Window) parentForm) == DialogResult.OK;
    }
    catch (Exception ex)
    {
      flag = false;
      throw;
    }
    finally
    {
      dprogressBarForm.StartProcess -= new CUiC3DProgressBarForm.CUiC3DProgressBarForm_StartProcessEventHandler(this.progressForm_StartProcess);
      dprogressBarForm.ProcessCanceled -= new CUiC3DProgressBarForm.CUiC3DProgressBarForm_ProcessCanceledEventHandler(this.progressForm_ProcessCanceled);
      ((Form) dprogressBarForm).Close();
    }
  }

  private bool GenerateRoot(CApC3DRootNodeData rootNode)
  {
    bool root = true;
    if (rootNode != null)
    {
      try
      {
        CApC3DAttachmentNameGenerator dattachmentNameGenerator = new CApC3DAttachmentNameGenerator();
        string animationFileName = dattachmentNameGenerator.GenerateAnimationFileName(rootNode.PlanningNodeObject, CApC3DUtils.PRCExtension);
        string dataFileName = dattachmentNameGenerator.GenerateDataFileName(rootNode.PlanningNodeObject);
        string nodesFileName = dattachmentNameGenerator.GenerateNodesFileName(rootNode.PlanningNodeObject);
        string str = this.DocumentationSettings.RecordAnimation ? dattachmentNameGenerator.GenerateAnimationFileName(rootNode.PlanningNodeObject, CApC3DUtils.JSExtension) : string.Empty;
        this.m_snapshotApp.CreateCurrentSnapshot();
        TxObjectList displayedObjects = new TxObjectList();
        CApC3DAppearanceSet appearanceSet = new CApC3DAppearanceSet();
        this.GetObjectsForExport((CApC3DProcessNodeData) rootNode, displayedObjects, appearanceSet);
        this.PrepareSceneForCreatingDataFile(displayedObjects);
        this.m_simulationApp.Initialize((CApC3DProcessNodeData) rootNode, animationFileName, str, this.DocumentationSettings, appearanceSet);
        this.m_simulationApp.StartStepRecording += new CApC3DSimulationApp.CApC3DSimulationApp_StartStepRecordingEventHandler(this.m_simulationApp_StartStepRecording);
        this.IncreaseProgressBar((object) this, new EventArgs());
        root = this.RecordObject((CApC3DProcessNodeData) rootNode);
        TxExportGraphicsAnimationOutputData animationOutputData = TxExportGraphicsAnimationEx.GetAnimationOutputData();
        this.m_simulationApp.StartStepRecording -= new CApC3DSimulationApp.CApC3DSimulationApp_StartStepRecordingEventHandler(this.m_simulationApp_StartStepRecording);
        this.m_simulationApp.Terminate();
        this.IncreaseProgressBar((object) this, new EventArgs());
        if (root)
        {
          this.m_snapshotApp.CreateDataFile((CApC3DProcessNodeData) rootNode, animationOutputData, dataFileName, this.DocumentationSettings, appearanceSet);
          this.m_snapshotApp.CreateNodesFile((CApC3DProcessNodeData) rootNode, animationOutputData, nodesFileName, this.DocumentationSettings);
          rootNode.Set3DAttachment(animationFileName, str, dataFileName, nodesFileName);
        }
      }
      catch (Exception ex)
      {
        throw;
      }
      finally
      {
        this.m_snapshotApp.RestoreCurrentSnapshot();
        this.m_snapshotApp.DeleteTempSnapshots((CApC3DProcessNodeData) rootNode);
      }
    }
    return root;
  }

  private void GetObjectsForExport(
    CApC3DProcessNodeData operation,
    TxObjectList displayedObjects,
    CApC3DAppearanceSet appearanceSet)
  {
    switch (this.DocumentationSettings.IncludedObjectsMode)
    {
      case CApC3DDocumentationSettings.CApC3DIncludedObjectsMode.OnlyDisplayedObjectsInScene:
        this.GetCurrentDisplayedObjects(displayedObjects, appearanceSet);
        break;
      case CApC3DDocumentationSettings.CApC3DIncludedObjectsMode.OnlyObjectsIncludedInSnapshotsAndSimulation:
        this.GetObjectsIncludedInSnapshots(displayedObjects, appearanceSet);
        if (this.DocumentationSettings.RecordAnimation)
        {
          this.GetObjectsIncludedInSimulationEvents(operation, displayedObjects, appearanceSet);
          break;
        }
        break;
      case CApC3DDocumentationSettings.CApC3DIncludedObjectsMode.AllLoadedObjects:
        TxApplication.ActiveDocument.PhysicalRoot.Display();
        this.GetCurrentDisplayedObjects(displayedObjects, appearanceSet);
        break;
    }
    this.RemoveIrrelevantObjects(displayedObjects, appearanceSet);
  }

  private void RemoveIrrelevantObjects(TxObjectList resultList, CApC3DAppearanceSet appearanceSet)
  {
    TxTypeFilter txTypeFilter = new TxTypeFilter();
    txTypeFilter.AddIncludedType(typeof (ITxComponent));
    txTypeFilter.AddIncludedType(typeof (TxKinematicLink));
    txTypeFilter.AddIncludedType(typeof (ITxGeometry));
    txTypeFilter.AddIncludedType(typeof (ITxGroup));
    txTypeFilter.AddIncludedType(typeof (TxNote));
    txTypeFilter.AddIncludedType(typeof (TxLinearDimension));
    txTypeFilter.AddIncludedType(typeof (TxFrame));
    txTypeFilter.AddIncludedType(typeof (TxPmi));
    TxObjectList txObjectList1 = txTypeFilter.Filter(resultList);
    ((Collection<ITxObject>) resultList).Clear();
    ((TxObjectList<ITxObject>) resultList).AddRange((TxObjectList<ITxObject>) txObjectList1);
    if (this.DocumentationSettings.PdfMode != null && this.DocumentationSettings.IncludePMIs)
      return;
    TxObjectList txObjectList2 = new TxObjectList();
    foreach (ITxObject result in (Collection<ITxObject>) resultList)
    {
      if (TxObjectEx.HasPMIType(result))
        ((Collection<ITxObject>) txObjectList2).Add(result);
    }
    foreach (ITxObject itxObject in (Collection<ITxObject>) txObjectList2)
    {
      if (!this.DocumentationSettings.IncludePMIs && itxObject is ITxDisplayableObject displayableObject)
        displayableObject.Blank();
      ((Collection<ITxObject>) resultList).Remove(itxObject);
      appearanceSet.Remove(itxObject as ITxDisplayableObject);
    }
  }

  private void PrepareSceneForCreatingDataFile(TxObjectList displayedObjects)
  {
    foreach (ITxDisplayableObject displayedObject in (Collection<ITxObject>) displayedObjects)
    {
      if (displayedObject is ITxComponent)
      {
        ITxDisplayableObject displayableObject = displayedObject;
        if (displayableObject != null)
        {
          displayableObject.RestoreColor();
          displayableObject.DisplayMode = (TxDisplayMode) 1;
        }
      }
    }
    TxApplication.RefreshDisplay();
  }

  private void GetObjectsIncludedInSnapshots(
    TxObjectList displayedObjects,
    CApC3DAppearanceSet appearanceSet)
  {
    this.GetObjectsIncludedInSnapshots(displayedObjects, appearanceSet, false);
  }

  private void GetObjectsIncludedInSimulationEvents(
    CApC3DProcessNodeData operationNode,
    TxObjectList displayedObjects,
    CApC3DAppearanceSet appearanceSet)
  {
    if (operationNode.IsStep && operationNode.NodeObject is ITxSimulationEventParentOperation nodeObject)
    {
      List<ITxSimulationEventParentOperation> source = new List<ITxSimulationEventParentOperation>();
      source.Add(nodeObject);
      if (nodeObject is ITxObjectCollection objectCollection)
      {
        TxTypeFilter txTypeFilter = new TxTypeFilter(typeof (ITxSimulationEventParentOperation));
        source.AddRange(((IEnumerable) objectCollection.GetAllDescendants((ITxTypeFilter) txTypeFilter)).Cast<ITxSimulationEventParentOperation>());
      }
      new List<ITxDisplayableObject>(new List<ITxObject>(source.SelectMany<ITxSimulationEventParentOperation, ITxObject>((Func<ITxSimulationEventParentOperation, IEnumerable<ITxObject>>) (obj => (IEnumerable<ITxObject>) obj.SimulationEvents))).SelectMany<ITxObject, ITxObject>((Func<ITxObject, IEnumerable<ITxObject>>) (obj =>
      {
        TxDisplayEvent txDisplayEvent = obj as TxDisplayEvent;
        return TxDisplayEvent.op_Inequality(txDisplayEvent, (ITxObject) null) ? (IEnumerable<ITxObject>) txDisplayEvent.ObjectsToDisplay : Enumerable.Empty<ITxObject>();
      })).Cast<ITxDisplayableObject>()).ForEach((Action<ITxDisplayableObject>) (obj =>
      {
        obj.Display();
        if (obj.Visibility != null && obj.Visibility != 1)
          return;
        this.AddRelevantObjects(obj, displayedObjects, appearanceSet, operationNode.AttachedSnapshotData.Snapshot);
      }));
    }
    operationNode.GetChildren(true).ForEach((Action<CApC3DProcessNodeData>) (child => this.GetObjectsIncludedInSimulationEvents(child, displayedObjects, appearanceSet)));
  }

  private void GetCurrentDisplayedObjects(
    TxObjectList allDisplayedObjects,
    CApC3DAppearanceSet appearanceSet)
  {
    foreach (ITxDisplayableObject allDescendant in (Collection<ITxObject>) TxApplication.ActiveDocument.PhysicalRoot.GetAllDescendants((ITxTypeFilter) new TxTypeFilter(typeof (ITxDisplayableObject))))
    {
      if (allDescendant.Visibility == null || allDescendant.Visibility == 1)
        ((Collection<ITxObject>) allDisplayedObjects).Add((ITxObject) allDescendant);
    }
    this.GetObjectsIncludedInSnapshots(new TxObjectList(), appearanceSet, true);
  }

  private void GetObjectsIncludedInSnapshots(
    TxObjectList displayedObjects,
    CApC3DAppearanceSet appearanceSet,
    bool currentlyVisibleOnly)
  {
    TxApplySnapshotParams applySnapshotParams = new TxApplySnapshotParams();
    applySnapshotParams.ObjectsLocation = true;
    applySnapshotParams.ObjectsVisibility = false;
    applySnapshotParams.PointOfView = false;
    applySnapshotParams.DevicePoses = false;
    applySnapshotParams.ObjectsAttachments = false;
    applySnapshotParams.ObjectsColor = true;
    applySnapshotParams.ObjectsViewingMode = false;
    applySnapshotParams.PMIsScale = true;
    TxObjectList txObjectList1 = new TxObjectList();
    TxObjectList txObjectList2;
    if (this.DocumentationSettings.StoreAllSnapshots)
    {
      txObjectList2 = this.GetAllSnapshots();
    }
    else
    {
      txObjectList2 = this.GetIncludedSnapshots();
      if (!((Collection<ITxObject>) txObjectList2).Contains((ITxObject) this.m_snapshotApp.CurrentSnapshot.Snapshot))
        ((Collection<ITxObject>) txObjectList2).Add((ITxObject) this.m_snapshotApp.CurrentSnapshot.Snapshot);
    }
    foreach (TxSnapshot snapshot in (Collection<ITxObject>) txObjectList2)
    {
      snapshot.Apply(applySnapshotParams);
      foreach (ITxDisplayableObject visibleObject in (Collection<ITxObject>) snapshot.VisibleObjects)
      {
        if (!currentlyVisibleOnly)
          visibleObject.Display();
        if (visibleObject.Visibility == null || visibleObject.Visibility == 1)
          this.AddRelevantObjects(visibleObject, displayedObjects, appearanceSet, snapshot);
      }
    }
    this.m_snapshotApp.RestoreCurrentSnapshot(false);
  }

  private void AddRelevantObjects(
    ITxDisplayableObject obj,
    TxObjectList allDisplayedObjectsInSnapshots,
    CApC3DAppearanceSet appearanceSet,
    TxSnapshot snapshot)
  {
    if (!((Collection<ITxObject>) allDisplayedObjectsInSnapshots).Contains((ITxObject) obj))
      ((Collection<ITxObject>) allDisplayedObjectsInSnapshots).Add((ITxObject) obj);
    appearanceSet.AddAppearance(obj, snapshot);
    if (obj is ITxObjectCollection objectCollection)
    {
      foreach (ITxDisplayableObject allDescendant in (Collection<ITxObject>) objectCollection.GetAllDescendants((ITxTypeFilter) new TxNoTypeFilter()))
      {
        if (!((Collection<ITxObject>) allDisplayedObjectsInSnapshots).Contains((ITxObject) allDescendant))
          ((Collection<ITxObject>) allDisplayedObjectsInSnapshots).Add((ITxObject) allDescendant);
        appearanceSet.AddAppearance(allDescendant, snapshot);
      }
    }
    for (ITxDisplayableObject collection = ((ITxObject) obj).Collection as ITxDisplayableObject; collection != null; collection = ((ITxObject) collection).Collection as ITxDisplayableObject)
    {
      if (!((Collection<ITxObject>) allDisplayedObjectsInSnapshots).Contains((ITxObject) collection))
        ((Collection<ITxObject>) allDisplayedObjectsInSnapshots).Add((ITxObject) collection);
    }
  }

  private TxObjectList GetIncludedSnapshots()
  {
    TxObjectList snapshotsList = new TxObjectList();
    foreach (CApC3DProcessNodeData root in this.m_dataManager.Roots)
      this.AddSnapsot(root, snapshotsList);
    return snapshotsList;
  }

  private void AddSnapsot(CApC3DProcessNodeData operation, TxObjectList snapshotsList)
  {
    if (operation.IsStep && !((Collection<ITxObject>) snapshotsList).Contains((ITxObject) operation.AttachedSnapshotData.Snapshot) && !operation.AttachedSnapshotData.IsCurrentView && !operation.AttachedSnapshotData.IsStartOperationView)
      ((Collection<ITxObject>) snapshotsList).Add((ITxObject) operation.AttachedSnapshotData.Snapshot);
    foreach (CApC3DProcessNodeData child in operation.GetChildren(true))
      this.AddSnapsot(child, snapshotsList);
  }

  private void m_simulationApp_StartStepRecording(
    object sender,
    CApC3DSimulationApp.CApC3DSimulationApp_StartStepRecordingEventArgs args)
  {
    this.m_snapshotApp.SetSnapshot(args.Step);
  }

  private bool RecordObject(CApC3DProcessNodeData operation)
  {
    bool flag = true;
    if (operation.IsStep)
    {
      if (this.DocumentationSettings.RecordAnimation)
      {
        this.ApplyFullSnapshot(operation.AttachedSnapshotData.Snapshot);
        flag = this.m_simulationApp.Record(operation);
      }
      else
        this.m_snapshotApp.SetSnapshot(operation);
      if (flag)
        this.IncreaseProgressBar((object) this, new EventArgs());
    }
    if (flag)
    {
      List<CApC3DProcessNodeData> children = operation.GetChildren(true);
      int count = children.Count;
      for (int index = 0; index < count & flag; ++index)
        flag = this.RecordObject(children[index]);
    }
    return flag;
  }

  private void ApplyFullSnapshot(TxSnapshot snapshot)
  {
    if (!TxSnapshot.op_Inequality(snapshot, (ITxObject) null))
      return;
    snapshot.Apply(new TxApplySnapshotParams()
    {
      ObjectsLocation = true,
      ObjectsVisibility = true,
      PointOfView = true,
      DevicePoses = true,
      ObjectsAttachments = true,
      ObjectsColor = true,
      ObjectsViewingMode = true,
      PMIsScale = true
    });
  }

  private void progressForm_StartProcess(object sender, EventArgs args)
  {
    bool flag = this.m_dataManager.AreRootsCheckedOut();
    if (!flag)
      throw new ApplicationException(CApC3DUtils.GetResourceManager().GetString("CREATE_3D_DOCUMENTATION_ROOT_CHECKEDOUT_BYOTHER"));
    int count = this.m_dataManager.Roots.Count;
    foreach (TxSnapshot txSnapshot in !this.DocumentationSettings.StoreAllSnapshots ? (Collection<ITxObject>) this.GetIncludedSnapshots() : (Collection<ITxObject>) this.GetAllSnapshots())
      txSnapshot.Apply(new TxApplySnapshotParams());
    for (int index = 0; index < count & flag; ++index)
      flag = this.GenerateRoot(this.m_dataManager.Roots[index] as CApC3DRootNodeData);
  }

  private void progressForm_ProcessCanceled(object sender, EventArgs args)
  {
    this.m_simulationApp.Cancel();
  }

  public delegate void CApC3DGeneratorApp_IncreaseProgressBarEventHandler(
    object sender,
    EventArgs args);
}
